package edu.northwestern.cbits.purple_robot_manager.logging;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import edu.northwestern.cbits.purple_robot_manager.activities.settings.LegacySettingsActivity;
import edu.northwestern.cbits.purple_robot_manager.activities.settings.SettingsActivity;
import edu.northwestern.cbits.purple_robot_manager.activities.settings.SettingsKeys;
import jscheme.JScheme;
import jscheme.SchemeException;
import jsint.Evaluator;
import jsint.Pair;
import jsint.Symbol;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import edu.northwestern.cbits.purple_robot_manager.R;
import edu.northwestern.cbits.purple_robot_manager.scripting.JSONHelper;
import edu.northwestern.cbits.purple_robot_manager.scripting.SchemeEngine;
public class SchemeConfigCheck extends SanityCheck
{
public String name(Context context)
{
return context.getString(R.string.name_scheme_config_check);
}
public void runCheck(Context context)
{
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
this._errorMessage = null;
this._errorLevel = SanityCheck.OK;
if (prefs.contains("scheme_config_contents") && prefs.getBoolean("check_scheme_config", true))
{
String schemeScript = prefs.getString("scheme_config_contents", "()");
Evaluator eval = new Evaluator();
eval.getInteractionEnvironment().setValue(Symbol.intern("PurpleRobot"), this);
eval.getInteractionEnvironment().setValue(Symbol.intern("JSONHelper"), new JSONHelper());
JScheme scheme = new JScheme(eval);
try
{
scheme.load(new InputStreamReader(context.getAssets().open("scheme/pregexp.scm")));
}
catch (IOException e)
{
LogManager.getInstance(context).logException(e);
}
catch (StackOverflowError e)
{
// Happens on older devices...
// LogManager.getInstance(context).logException(e);
}
try
{
scheme.load(new InputStreamReader(context.getAssets().open("scheme/json.scm")));
}
catch (IOException | StackOverflowError e)
{
LogManager.getInstance(context).logException(e);
}
try
{
scheme.load(new InputStreamReader(context.getAssets().open("scheme/purple-robot.scm")));
}
catch (IOException | StackOverflowError e)
{
LogManager.getInstance(context).logException(e);
}
try
{
Object sexp = scheme.read(schemeScript);
if (sexp instanceof Pair)
{
Pair pair = (Pair) sexp;
List<Map<String, Object>> configs = SchemeConfigCheck.parseConfigMaps(pair);
if (configs.size() > 0)
{
for (Map<String, Object> config : configs)
{
for (String key : config.keySet())
{
if (prefs.contains(key))
{
Object cfgObject = config.get(key);
if (cfgObject instanceof Boolean)
{
Boolean setting = (Boolean) cfgObject;
boolean pref = prefs.getBoolean(key, (setting == false));
if (pref != setting)
{
this._errorLevel = SanityCheck.WARNING;
this._errorMessage = context.getString(
R.string.scheme_config_check_changed, key);
}
}
else if (cfgObject instanceof String)
{
String pref = prefs.getString(key, null);
if (cfgObject.toString().equals(pref) == false)
{
boolean mismatched = true;
if (SettingsKeys.CONFIG_URL.equals(key))
{
if (pref.indexOf(cfgObject.toString()) == 0)
mismatched = false;
}
if (mismatched)
{
this._errorLevel = SanityCheck.WARNING;
this._errorMessage = context.getString(R.string.scheme_config_check_changed, key);
}
}
}
}
else
{
this._errorLevel = SanityCheck.ERROR;
this._errorMessage = context.getString(R.string.scheme_config_check_missing, key);
return;
}
}
}
}
}
}
catch (SchemeException e)
{
this._errorLevel = SanityCheck.ERROR;
this._errorMessage = context.getString(R.string.scheme_config_invalid_config);
LogManager.getInstance(context).logException(e);
}
}
}
private static List<Map<String, Object>> parseConfigMaps(Pair pair)
{
ArrayList<Map<String, Object>> maps = new ArrayList<>();
Object first = pair.first;
Object rest = pair.rest;
if (first instanceof Symbol && "pr-update-config".equals(first.toString()) && rest instanceof Pair)
{
Pair restPair = (Pair) rest;
restPair = (Pair) restPair.first;
restPair = (Pair) restPair.rest;
restPair = (Pair) restPair.first;
Map<String, Object> map = SchemeEngine.parsePairList(restPair);
maps.add(map);
}
else
{
if (first instanceof Pair)
{
Pair firstPair = (Pair) first;
List<Map<String, Object>> configs = SchemeConfigCheck.parseConfigMaps(firstPair);
if (configs.size() > 0)
maps.addAll(configs);
}
if (rest instanceof Pair)
{
Pair restPair = (Pair) rest;
if (((Pair) rest).isEmpty() == false)
{
List<Map<String, Object>> configs = SchemeConfigCheck.parseConfigMaps(restPair);
if (configs.size() > 0)
maps.addAll(configs);
}
}
}
return maps;
}
public Runnable getAction(final Context context)
{
Runnable r = new Runnable()
{
public void run()
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.ICE_CREAM_SANDWICH)
{
Intent intent = new Intent(context, LegacySettingsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
else
{
Intent intent = new Intent(context, SettingsActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
}
};
return r;
}
}